﻿using System;
using System.Reflection;
using Shared;
using Shared.NetWork;

namespace WorldServer
{
    class Program
    {
        static public WorldConfig Config = null;

        static void Main(string[] args)
        {
            Console.BufferWidth = 150;
            Console.Title = "World Server";
            new System.Threading.Thread(titleDisplay).Start();

            //Load Resources
            new System.Threading.Thread(loadDLL).Start();

            // Loading log level from file
            if (!Log.InitLog("Configs/World.log", "World"))
                WaitAndExit();

            // Loading all configs files
            ConfigMgr.LoadConfigs();
            Config = ConfigMgr.GetConfig<WorldConfig>();

            // Starting Remoting Server
            if (!RpcClient.InitRpcClient("WorldServer", Config.RpcKey,Config.RpcIp, Config.RpcPort))
                WaitAndExit();

            // Creating Remote objects
            AccountMgr.Instance = new AccountMgr();
            CharacterMgr.Instance = new CharacterMgr();
            CacheMgr.Instance = new CacheMgr();

            // Listening Client
            if (!TCPManager.Listen<RiftServer>(Config.WorldServerPort, "WorldServer"))
                WaitAndExit();

            Realm Rm = CharacterMgr.Instance.RegisterRealm(Config.RealmId, Config.WorldServerIP, Config.WorldServerPort, RpcClient.GetRpcClientId("WorldServer"));
            if (Rm == null)
            {
                Log.Error("WorldServer", "Invalid Realm : " + Config.RealmId);
                WaitAndExit();
            }

            ConsoleMgr.Start();
        }

        static public void WaitAndExit()
        {
            System.Threading.Thread.Sleep(2000);
            Environment.Exit(0);
        }

        static public void titleDisplay()
        {
            var oldTitle = Console.Title;
            while (true)
            {
                Console.Title = oldTitle + " [Total Memory: " + GC.GetTotalMemory(false) + "K]";
                System.Threading.Thread.Sleep(1000);
            }
        }

        static public void loadDLL()
        {
            while (true)
            {
                try
                {
                    AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
                    {
                        var derp = Assembly.GetExecutingAssembly().GetManifestResourceNames();
                        String resourceName = "WorldServer." + new AssemblyName(args.Name).Name + ".dll";
                        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
                        {
                            Byte[] assemblyData = new Byte[stream.Length];
                            stream.Read(assemblyData, 0, assemblyData.Length);
                            return Assembly.Load(assemblyData);
                        }
                    };
                }
                catch (Exception)
                {
                    break;
                }
            }
        }
    }
}
